﻿#region Copyright Notice
// 
// 
//  
//  Copyright (c) 2009-2011 Anindya Chatterjee
//  
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//  
//      http://www.apache.org/licenses/LICENSE-2.0
//  
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// 
// 
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using AbstractClass;
using AbstractClass.Collections.Generic;
using AbstractClass.Extensions;
using NUnit.Framework;

namespace QuasarTest.Core
{
    [TestFixture]
    public class TreeTest
    {
        #region Setup/Teardown

        [SetUp]
        public void Init()
        {
            _tree = new Tree<int>();
            foreach (int element in Enumerable.Range(0, 10))
            {
                Assert.IsTrue(_tree.AddNode(element));
            }
        }

        #endregion

        private Tree<int> _tree;

        [Test]
        public void TestAddNode()
        {
            Assert.AreEqual(_tree.Count, 10);
            int count = 0;

            Assert.AreEqual(_tree.Root.Value, 0);

            foreach (int element in Enumerable.Range(10, 10))
            {
                Assert.IsTrue(_tree.AddNode(element, count++));
            }
            Assert.AreEqual(_tree.Root.Value, 10);
            Assert.AreEqual(_tree.Count, 20);
        }


        [Test]
        public void TestClear()
        {
            _tree.Clear();
            Assert.AreEqual(_tree.Count, 0);
        }

        [Test]
        public void TestDeleteNode()
        {
            Assert.AreEqual(_tree.Count, 10);
            Assert.AreEqual(_tree.Root.Value, 0);
            _tree.DeleteNode(0);
            Assert.AreEqual(_tree.Count, 9);
            Assert.AreEqual(_tree.Root.Value, 1);
            _tree.DeleteNode(3);
            Assert.AreEqual(_tree.Count, 8);
            Assert.AreEqual(_tree.Root.Value, 1);
            _tree.DeleteNode(9);
            Assert.AreEqual(_tree.Count, 7);
            Assert.AreEqual(_tree.Root.Value, 1);
            _tree.DeleteNode(1);
            Assert.AreEqual(_tree.Root.Value, 2);
            Assert.AreEqual(_tree.Count, 6);
            Assert.AreEqual(_tree.Root.Value, 2);
        }

        [Test]
        public void TestGetSubTree()
        {
            TreeNode<int> newRoot = _tree.TryGetNode(5);
            Assert.NotNull(newRoot);
            var tree = (Tree<int>) _tree.GetSubtree(newRoot).Clone();
            Assert.AreEqual(tree.Count, 5);

            Assert.IsTrue(tree.AddNode(99));
            Assert.IsTrue(tree.HasNode(99));
            Assert.IsFalse(_tree.HasNode(99));
            Assert.AreEqual(tree.Count, 6);
        }


        [Test]
        public void TestIndexer()
        {
            Assert.AreEqual(_tree[2].FirstOrDefault().Value, 2);
            _tree[3] = Enumerable.Range(100, 10).Select(x => new TreeNode<int>(x));
            Assert.IsTrue(_tree.HasNode(100));
            Assert.AreEqual(_tree[3].Last().Value, 109);
        }

        [Test]
        public void TestLeastCommonAncestor()
        {
            var tree = new Tree<int>
                           {
                               Root = new TreeNode<int>(0,
                                                        new TreeNode<int>(1,
                                                                          new TreeNode<int>(2),
                                                                          new TreeNode<int>(3),
                                                                          new TreeNode<int>(4,
                                                                                            new TreeNode<int>(5),
                                                                                            new TreeNode<int>(6))
                                                            ),
                                                        new TreeNode<int>(7,
                                                                          new TreeNode<int>(8),
                                                                          new TreeNode<int>(9)
                                                            )
                                   )
                           };

            TreeNode<int> three = tree.TryGetNode(3);
            TreeNode<int> six = tree.TryGetNode(6);
            TreeNode<int> one = tree.TryGetNode(1);

            TreeNode<int> node = Tree<int>.LeastCommonAncestor(three, six);
            Assert.AreEqual(node, one);
        }

        [Test]
        public void TestLeaves()
        {
            Assert.AreEqual(_tree.Leaves.Count(), 1);
            Assert.AreEqual(_tree.Leaves.Last().Value, 9);
            _tree.AddNode(10);
            Assert.AreEqual(_tree.Leaves.Last().Value, 10);
            Assert.AreEqual(_tree.Leaves.Count(), 1);
            Assert.AreEqual(_tree.Leaves.Last().Depth, 10);
            _tree[10] = Enumerable.Range(11, 2).Select(x => new TreeNode<int>(x));
            Assert.AreEqual(_tree.Leaves.Count(), 3);
        }

        [Test]
        public void TestRemove()
        {
            const string strA = "Anindya";
            string res = strA.Remove('a', 0, false);
            Console.WriteLine(res);
        }

        [Test]
        public void TestTesta()
        {
            ComplexNumber cmp;
            ComplexNumber.TryParse("asas", out cmp);
            Console.WriteLine(cmp);
        }

        [Test]
        public void TestTraverse()
        {
            var bfsList = new List<int>();
            var dfsList = new List<int>();

            _tree.AddNode(30, 2);
            _tree.Traverse(x => bfsList.Add(x.Value), TraversalOrder.BreadthFirst);
            _tree.Traverse(x => dfsList.Add(x.Value), TraversalOrder.DepthFirst);

            Assert.AreNotEqual(bfsList.IndexOf(30), dfsList.IndexOf(30));
            Assert.AreEqual(dfsList.Last(), 30);
            Assert.AreEqual(bfsList.IndexOf(2), bfsList.IndexOf(30) - 1);
        }
    }
}